using Headsight.BPMN2WF.BPMN.BlockModel;
using Headsight.BPMN2WF.BPMN.Model;
using Headsight.BPMN2WF.BPMN.Schemas;
using Headsight.BPMN2WF.Transformation.Transformers;

namespace Headsight.BPMN2WF.Transformation.BPMN2TransformerMappings
{
    /// <summary>
    /// <see cref="IBPMN2WFTransformations"/> default implementation.
    /// </summary>
    public class BPMN2WFTransformationVNext : IBPMN2WFTransformations
    {
        public IBPMN2WFTransformation Get(BPMNFlowNode flowNode)
        {
            var actualFlowNode = (flowNode is BPMNFlowNodesBlock)
                                     ? ((BPMNFlowNodesBlock) flowNode).FlowNodeIn
                                     : flowNode;

            var typeOfFlowElement = actualFlowNode.TElement.GetType();

            if (flowNode is BPMNFlowNodesBlockEmpty)
            {
                return new BPMN2WFTransformationDummyActivity();
            }

            if (typeof(tExclusiveGateway).IsAssignableFrom(typeOfFlowElement) && flowNode is BPMNFlowNodesBlock )
            {
                return new BPMN2WFTransformationExclusiveGateway();
            }

            if (typeof(tInclusiveGateway).IsAssignableFrom(typeOfFlowElement) && flowNode is BPMNFlowNodesBlock)
            {
                return new BPMN2WFTransformationExclusiveGateway();
                //return new BPMN2WFTransformationInclusiveGateway();
            }

            if (typeof(tGateway).IsAssignableFrom(typeOfFlowElement) && flowNode is BPMNFlowNodesBlock)
            {
                return new BPMN2WFTransformationExclusiveGateway();
            }

            // flowNode isn't BPMNProcessBlock and therefore the respective flowNode should be
            // a converging node if assigable from typeOfFlowElement... This is probably not
            // the final way to go... Anyhow this shows me visually respective converging
            // elements (to think further about the corret (gateway-specific) WF-counterpart transformations).
            if (typeof(tGateway).IsAssignableFrom(typeOfFlowElement))
            {
                return new BPMN2WFTransformationConvergingActivity();
            }

            if (flowNode is BPMNFlowNodesBlock)
            {
                return new BPMN2WFTransformationFlowchart();
            }

            if (typeof(tUserTask).IsAssignableFrom(typeOfFlowElement))
            {
                return new BPMN2WFTransformationCustomWFUserTask();
            }

            if (typeof(tEndEvent).IsAssignableFrom(typeOfFlowElement))
            {
                return new BPMN2WFTransformationTerminateEndEvent();
            }

            // No mapping found? Use default transformations strategy (in future of course
            // the default transformation strategies are not using WF4.x WriteLine but
            // better suited WF4.x activities.
            return new BPMN2WFTransformationWriteLine();
        }
    }
}